package com.example.sample.util;

import android.Manifest.permission;
import android.Manifest.permission_group;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;

import net.liteheaven.xblib.common.log.XLog;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;

/**
 * Created by LiangYu on 2018/4/9.
 */
public class MPermissionDelegate{

    public static final String TAG = "MPermissionDelegate";
    private static final int REQ_PERMISSION = 10000;
    private Activity host;
    private String [] requiredPermissions;
    private PermissionResultCallback callback;

    public MPermissionDelegate(Activity host){
        this.host = host;
    }

    public void checkPermissions(String [] permissions, PermissionResultCallback callback){
        this.requiredPermissions = permissions;
        this.callback = callback;
        checkPermissionsInner();
    }

    private void checkPermissionsInner(){
        String [] permissions = requiredPermissions;
        ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i<permissions.length; i++){
            if (!isPermissionGranted(host, permissions[i])){
                list.add(permissions[i]);
            }
        }
        log("check permissions " + permissions);
        String [] undone = list.toArray(new String[list.size()]);
        if (undone != null && undone.length > 0){
            requestPermissions(undone);
        }else{
            onSuccess();
        }
    }

    private void requestPermissions(String [] permissions){
        ActivityCompat.requestPermissions(host, permissions, REQ_PERMISSION);
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQ_PERMISSION:{
                log("check permission result content = " + permissions + " result = " + grantResults);
                List<String> failed = new ArrayList<String>();
                List<String> ban = new ArrayList<String>();
                for (int i = 0; i<permissions.length; i++){
                    int grantResult = grantResults[i];
                    String permission = permissions[i];

                    if (grantResult != PERMISSION_GRANTED){
                        failed.add(permission);
                        if (!ActivityCompat.shouldShowRequestPermissionRationale(host, permission)){
                            ban.add(permission);
                        }
                    }
                }

                if (!failed.isEmpty()){
                    if (!ban.isEmpty()){
                        showBanDialog(ban.get(0));
                    }else{
                        showAllowDialog(failed);
                    }
                }else{
                    onSuccess();
                }
            }
            break;
        }
    }

    private void showBanDialog(String permission){
        String group = getGroupByPermission(permission);
        PermissionGroupInfo groupInfo = getGroupInfo(group);
        String explanation = groupInfo.explanation;
        if (TextUtils.isEmpty(explanation)){
            explanation = "在设置-应用-"+getAppName()+"-权限中开启"+groupInfo.description+"权限，以正常使用"+getAppName()+"的功能";
        }

        String title = "权限申请";
        new AlertDialog.Builder(host)
                .setTitle(title)
                .setMessage(explanation)
                .setCancelable(false)
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        onFailure(true);
                    }
                })
                .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent();
                        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        intent.setData(Uri.fromParts("package", host.getPackageName(), null));
                        host.startActivity(intent);
                        host.finish();
                    }
                })
                .create()
                .show();
    }

    private void showAllowDialog(List<String> permissions){
        String desc = getDescription(permissions);
        String title = "权限申请";
        String content = "没有" + desc + "权限，功能将无法使用，是否申请权限？";
        new AlertDialog.Builder(host)
                .setTitle(title)
                .setMessage(content)
                .setCancelable(false)
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        onFailure(false);
                    }
                })
                .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        checkPermissionsInner();
                    }
                })
                .create()
                .show();
    }

    private void onSuccess(){
        log("permission success.");
        if (callback != null){
            callback.onSuccess();
        }
    }

    private void onFailure(boolean isBan){
        log("permission failure.");
        if (callback != null){
            callback.onFailure(isBan);
        }
    }

    public interface PermissionResultCallback{
        void onSuccess();

        /**
         *
         * @param isBan false是普通取消,true是下次不再询问的拒绝
         */
        void onFailure(boolean isBan);
    }

    public static class PermissionGroupInfo{
        public String name;
        public String description;
        public String explanation;
        public PermissionGroupInfo(String name, String description, String explanation){
            this.name = name;
            this.description = description;
            this.explanation = explanation;
        }
    }

    private PermissionGroupInfo [] groupInfo = new PermissionGroupInfo[]{
            new PermissionGroupInfo(permission_group.CONTACTS, "联系人", ""),
            new PermissionGroupInfo(permission_group.PHONE, "电话", getAppName()+"使用电话权限确定本机号码和设备ID，以保证账号登录的安全性。"+getAppName()+"不会拨打其他号码或终止通话。请在设置-应用-"+getAppName()+"-权限中开启电话权限，以正常登录"+getAppName()+"。"),
            new PermissionGroupInfo(permission_group.CALENDAR, "日程", ""),
            new PermissionGroupInfo(permission_group.CAMERA, "相机", ""),
            new PermissionGroupInfo(permission_group.SENSORS, "身体传感器", ""),
            new PermissionGroupInfo(permission_group.LOCATION, "位置", ""),
            new PermissionGroupInfo(permission_group.STORAGE, "存储", ""),
            new PermissionGroupInfo(permission_group.MICROPHONE, "录音", ""),
            new PermissionGroupInfo(permission_group.SMS, "短信", ""),
    };

    public static class PermissionInfo {
        public String permission;
        public String description;
        public String group;
        public PermissionInfo(String permission, String description, String group){
            this.permission = permission;
            this.description = description;
            this.group = group;
        }
    }

    private PermissionInfo[] permissionStore = new PermissionInfo[]{
            new PermissionInfo(permission.READ_CONTACTS, "读取联系人", permission_group.CONTACTS),
            new PermissionInfo(permission.WRITE_CONTACTS, "写入联系人", permission_group.CONTACTS),
            new PermissionInfo(permission.GET_ACCOUNTS, "访问账户Gmail列表", permission_group.CONTACTS),

            new PermissionInfo(permission.READ_CALL_LOG, "读取呼叫日志", permission_group.PHONE),
            new PermissionInfo(permission.WRITE_CALL_LOG, "写入呼叫日志", permission_group.PHONE),
            new PermissionInfo(permission.READ_PHONE_STATE, "读取电话状态", permission_group.PHONE),
            new PermissionInfo(permission.CALL_PHONE, "拨打电话", permission_group.PHONE),
            new PermissionInfo(permission.USE_SIP, "使用SIP视频", permission_group.PHONE),
            new PermissionInfo(permission.PROCESS_OUTGOING_CALLS, "处理拨出电话", permission_group.PHONE),

            new PermissionInfo(permission.READ_CALENDAR, "读取日程提醒", permission_group.CALENDAR),
            new PermissionInfo(permission.WRITE_CALENDAR, "写入日程提醒", permission_group.CALENDAR),

            new PermissionInfo(permission.CAMERA, "拍照", permission_group.CAMERA),

            new PermissionInfo(permission.BODY_SENSORS, "身体传感器", permission_group.SENSORS),

            new PermissionInfo(permission.ACCESS_FINE_LOCATION, "获取精确位置", permission_group.LOCATION),
            new PermissionInfo(permission.ACCESS_COARSE_LOCATION, "获取粗略位置", permission_group.LOCATION),

            new PermissionInfo(permission.READ_EXTERNAL_STORAGE, "读取外部存储", permission_group.STORAGE),
            new PermissionInfo(permission.WRITE_EXTERNAL_STORAGE, "写入外部存储", permission_group.STORAGE),

            new PermissionInfo(permission.RECORD_AUDIO, "录音", permission_group.MICROPHONE),

            new PermissionInfo(permission.READ_SMS, "读取呼叫日志", permission_group.SMS),
            new PermissionInfo(permission.RECEIVE_WAP_PUSH, "接收WAP推送", permission_group.SMS),
            new PermissionInfo(permission.RECEIVE_MMS, "接收彩信", permission_group.SMS),
            new PermissionInfo(permission.RECEIVE_SMS, "接收短信", permission_group.SMS),
            new PermissionInfo(permission.SEND_SMS, "发送短信", permission_group.SMS),
    };

    private String getDescription(List<String> permissions){
        List<String> groups = getGroupsByPermissions(permissions);

        List<String> groupDescriptions = new ArrayList<String>();
        for (String group:groups) {
            groupDescriptions.add(getGroupInfo(group).description);
        }

        String str = getStr(groupDescriptions);
        return str;
    }

    private List<String> getGroupsByPermissions(List<String> permissions){
        List<String> groups = new ArrayList<String>();
        for (int i = 0; i<permissions.size(); i++){
            String permission = permissions.get(i);
            String group = getGroupByPermission(permission);
            if (!groups.contains(group)){
                groups.add(group);
            }
        }
        return groups;
    }

    private String getGroupByPermission(String permission){
        for (int j = 0; j<permissionStore.length; j++){
            PermissionInfo info = permissionStore[j];
            if (info.permission.equals(permission)){
                String group = info.group;
                return group;
            }
        }
        return "";
    }

    private PermissionGroupInfo getGroupInfo(String group){
        for (int j = 0; j<groupInfo.length; j++){
            PermissionGroupInfo info = groupInfo[j];
            if (info.name.equals(group)){
                return info;
            }
        }
        return null;
    }

    /**
     * 把数组拼成字符串显示
     */
    private String getStr(List<String> items){
        StringBuffer result = new StringBuffer();
        for (int i = 0; i< items.size(); i++){
            String item = items.get(i);
            result.append("“");
            result.append(item);
            result.append("”");
            if (i != items.size() - 1){
                result.append("、");
            }
        }
        return result.toString();
    }

    private String getAppName(){
        return "160医生";
    }

    public static boolean isPermissionGranted(Context context, String permission) {
        return isPermissionsGranted(context, new String[]{permission});
    }

    public static boolean isPermissionsGranted(Context context, String[] permissions) {
        boolean result = true;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            for (int i = 0; i < permissions.length; i++) {
                if (PERMISSION_GRANTED != ContextCompat.checkSelfPermission(context, permissions[i])) {
                    result = false;
                    break;
                }
            }
        }
        return result;
    }

    public static String [] getBasePermissions(){
        String[] permissions = new String[]{
                permission.READ_PHONE_STATE,
                permission.READ_EXTERNAL_STORAGE,
                permission.WRITE_EXTERNAL_STORAGE
        };
        return permissions;
    }


    private void log(String content){
        XLog.d(TAG, content);
    }
}